package cn.kkdlk.generate.dxf.model.base;

import cn.kkdlk.generate.dxf.util.StringUtil;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Color {
    /**
     * The color white.  In the default sRGB space.
     */
    public final static Color white = new Color(255, 255, 255);

    /**
     * The color white.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color WHITE = white;


    /**
     * The color light gray.  In the default sRGB space.
     */
    public final static Color lightGray = new Color(192, 192, 192);

    /**
     * The color light gray.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color LIGHT_GRAY = lightGray;

    /**
     * The color gray.  In the default sRGB space.
     */
    public final static Color gray = new Color(128, 128, 128);

    /**
     * The color gray.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color GRAY = gray;

    /**
     * The color dark gray.  In the default sRGB space.
     */
    public final static Color darkGray = new Color(64, 64, 64);

    /**
     * The color dark gray.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color DARK_GRAY = darkGray;

    /**
     * The color black.  In the default sRGB space.
     */
    public final static Color black = new Color(0, 0, 0);

    /**
     * The color black.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color BLACK = black;

    /**
     * The color red.  In the default sRGB space.
     */
    public final static Color red = new Color(255, 0, 0);

    /**
     * The color red.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color RED = red;

    /**
     * The color pink.  In the default sRGB space.
     */
    public final static Color pink = new Color(255, 175, 175);

    /**
     * The color pink.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color PINK = pink;

    /**
     * The color orange.  In the default sRGB space.
     */
    public final static Color orange = new Color(255, 200, 0);

    /**
     * The color orange.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color ORANGE = orange;

    /**
     * The color yellow.  In the default sRGB space.
     */
    public final static Color yellow = new Color(255, 255, 0);

    /**
     * The color yellow.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color YELLOW = yellow;

    /**
     * The color green.  In the default sRGB space.
     */
    public final static Color green = new Color(0, 255, 0);

    /**
     * The color green.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color GREEN = green;

    /**
     * The color magenta.  In the default sRGB space.
     */
    public final static Color magenta = new Color(255, 0, 255);

    /**
     * The color magenta.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color MAGENTA = magenta;

    /**
     * The color cyan.  In the default sRGB space.
     */
    public final static Color cyan = new Color(0, 255, 255);

    /**
     * The color cyan.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color CYAN = cyan;

    /**
     * The color blue.  In the default sRGB space.
     */
    public final static Color blue = new Color(0, 0, 255);

    /**
     * The color blue.  In the default sRGB space.
     *
     * @since 1.4
     */
    public final static Color BLUE = blue;


    private int mR;
    private int mG;
    private int mB;
    private float mA;

    public Color(int red, int green, int blue, float alpha) {
        this.mR = red;
        this.mG = green;
        this.mB = blue;
        this.mA = alpha;
    }

    public Color(int red, int green, int blue) {
        this(red, green, blue, 1.0f);
    }

    public static Color fromRGBA(int red, int green, int blue, float alpha) {
        return new Color(red, green, blue, alpha);
    }

    public static Color fromHex(String hex) {
        hex = hex.replace("#", "");
        int red = Integer.parseInt(hex.substring(0, 2), 16);
        int green = Integer.parseInt(hex.substring(2, 4), 16);
        int blue = Integer.parseInt(hex.substring(4, 6), 16);
        float alpha = hex.length() == 8 ? Integer.parseInt(hex.substring(6, 8), 16) / 255.0f : 1.0f;
        return new Color(red, green, blue, alpha);
    }

    /**
     * rgba 或 rgb 格式颜色转Color对象
     *
     * @param rgbaString
     * @return
     */
    public static Color fromRGBAString(String rgbaString) throws IllegalArgumentException {
        Pattern pattern = Pattern.compile("(rgba|rgb)\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)");
        Matcher matcher = pattern.matcher(rgbaString);
        if (matcher.matches()) {
            int red = Integer.parseInt(matcher.group(2));
            int green = Integer.parseInt(matcher.group(3));
            int blue = Integer.parseInt(matcher.group(4));
            float alpha = matcher.group(5) != null ? Float.parseFloat(matcher.group(5)) : 1.0f;
            return new Color(red, green, blue, alpha);
        } else {
            throw new IllegalArgumentException("Invalid RGBA color string: " + rgbaString);
        }
    }

    /**
     * 字符串颜色 支持rgba() rgb  16进制颜色 转为Color对象
     *
     * @param colorStr
     * @return
     */
    public static Color colorStringToHex(String colorStr) throws IllegalArgumentException {
        if (colorStr.contains("rgb") || colorStr.contains("rgba")) {
            return fromRGBAString(colorStr);
        } else {
            return fromHex(colorStr);
        }
    }

    /**
     * 字符串颜色 支持 rgba rgb 16进制 转Color，如果为空则使用默认颜色
     *
     * @param colorStr
     * @param defaultColor
     * @return
     */
    public static Color colorStringToHex(String colorStr, String defaultColor) {
        try {
            if (StringUtil.isNotBlank(colorStr)) {
                return Color.colorStringToHex(colorStr);
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        return Color.colorStringToHex(defaultColor);
    }

    /**
     * 字符串颜色 支持 rgba rgb 16进制 转Color，如果为空则使用默认颜色
     *
     * @param colorStr
     * @param defaultColor
     * @return
     */
    public static Color colorStringToHex(String colorStr, Color defaultColor) {
        try {
            if (StringUtil.isNotBlank(colorStr)) {
                return Color.colorStringToHex(colorStr);
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        return defaultColor;
    }

    /**
     * 当给定一个颜色的十六进制值和透明度（0-1）生成相应的RGBA值：
     * @param hex
     * @param alpha
     * @return
     */
    public static String hexSetAlphaToRgba(String hex, float alpha) {
        hex = hex.replace("#", "");
        int red = Integer.parseInt(hex.substring(0, 2), 16);
        int green = Integer.parseInt(hex.substring(2, 4), 16);
        int blue = Integer.parseInt(hex.substring(4, 6), 16);
        return new Color(red, green, blue, alpha).toRGBA();
    }


    public String toABGRHex() {
        int alpha = (int) (this.getAlpha() * 255); // 将 alpha 转换为 [0, 255]
        int red = this.getRed();
        int green = this.getGreen();
        int blue = this.getBlue();

        StringBuilder hex = new StringBuilder("#");
        hex.append(formatByteToHex(alpha));
        hex.append(formatByteToHex(blue));
        hex.append(formatByteToHex(green));
        hex.append(formatByteToHex(red));
        return hex.toString();
    }


    public String toRGBA() {
        String sb = "rgba(" +
                mR +
                "," +
                mG +
                "," +
                mB +
                "," +
                mA +
                ")";
        return sb;
    }


    public int toRGB() {
        // 1. 将透明度转换为不透明度
        float opacity = 1.0f - this.getAlpha(); // 关键转换！
        // 2. 计算不透明度的整数值 [0-255]
        int opacityInt = Math.round(opacity * 255);
        opacityInt = Math.max(0, Math.min(opacityInt, 255));

        return ((opacityInt & 0xFF) << 24) |
                ((this.getRed() & 0xFF) << 16) |
                ((this.getGreen() & 0xFF) << 8) |
                ((this.getBlue() & 0xFF));
    }


    public String toHex() {
        int alpha = (int) (this.getAlpha() * 255); // 将 alpha 转换为 [0, 255]
        int red = this.getRed();
        int green = this.getGreen();
        int blue = this.getBlue();
        StringBuilder hex = new StringBuilder("#");
        hex.append(formatByteToHex(red));
        hex.append(formatByteToHex(green));
        hex.append(formatByteToHex(blue));
        hex.append(formatByteToHex(alpha));
        return hex.toString();
    }

    private String formatByteToHex(int value) {
        if (value < 0 || value > 255) {
            throw new IllegalArgumentException("Color component must be between 0 and 255: " + value);
        }
        return String.format("%02X", value);
    }


    public long toCADColor() {
        // 1. 将透明度转换为不透明度
        float opacity = 1.0f - this.getAlpha(); // 关键转换！
        // 2. 计算不透明度的整数值 [0-255]
        int opacityInt = Math.round(opacity * 255);
        opacityInt = Math.max(0, Math.min(opacityInt, 255));
        // 3. 创建 ARGB 值（A = 不透明度）
        long argbValue = ((long) opacityInt << 24) |
                ((long) this.getRed() << 16) |
                ((long) this.getGreen() << 8) |
                this.getBlue();
        // 4. 返回无符号 32 位整数
        return argbValue;
    }


    public int getRed() {
        return mR;
    }

    public void setRed(int red) {
        this.mR = red;
    }

    public int getGreen() {
        return mG;
    }

    public void setGreen(int green) {
        this.mG = green;
    }

    public int getBlue() {
        return mB;
    }

    public void setBlue(int blue) {
        this.mB = blue;
    }

    public float getAlpha() {
        return mA;
    }

    public void setAlpha(float alpha) {
        this.mA = alpha;
    }

    @Override
    public String toString() {
        return "Color{" +
                "red=" + mR +
                ", green=" + mG +
                ", blue=" + mB +
                ", alpha=" + mA +
                '}';
    }
}
